﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SIA.Configurators;
using AODL.Document.SpreadsheetDocuments;
using AODL.Document.Content.Tables;

namespace SIA.Configurators.ods
{
    public class OdsDictionaryProperty : AbstractDictionaryProperty
    {
        private String _directory;
        private System.IO.FileSystemWatcher _fsw;
        public String Directory { get { return _directory; } }

        public OdsDictionaryProperty(String directory)
        {
            if (!System.IO.Directory.Exists(directory)) throw new System.IO.DirectoryNotFoundException();

            this._directory = directory;

            load();


            _fsw = new System.IO.FileSystemWatcher(_directory, "*.ods");
            _fsw.Created += new System.IO.FileSystemEventHandler(_fsw_Created);
            _fsw.Deleted += new System.IO.FileSystemEventHandler(_fsw_Deleted);
            _fsw.Renamed += new System.IO.RenamedEventHandler(_fsw_Renamed);
            _fsw.EnableRaisingEvents = true;                                        
        }

        void _fsw_Renamed(object sender, System.IO.RenamedEventArgs e)
        {
            this.Remove(e.OldName);
            this.Add(e.Name, new OdsTablesDictionaryProperty(e.FullPath));
        }

        void _fsw_Deleted(object sender, System.IO.FileSystemEventArgs e)
        {
            this.Remove(e.Name);
        }

        void _fsw_Created(object sender, System.IO.FileSystemEventArgs e)
        {
            Add(e.Name, new OdsTablesDictionaryProperty(e.FullPath));         
        }

        public override void load()
        {
            this.Clear();

            foreach (String str in System.IO.Directory.GetFiles(_directory, "*.ods", System.IO.SearchOption.AllDirectories))
            {
                String key = str.Substring(str.LastIndexOf(System.IO.Path.DirectorySeparatorChar)+1);
                if (!this.ContainsKey(key))
                    Add(key, new OdsTablesDictionaryProperty(str));
            }
        }
    }

    public class OdsTablesDictionaryProperty : AbstractDictionaryProperty
    {
        private String _nomeFile;
        private DateTime _lastWrite;
        private System.IO.FileSystemWatcher _fsw;

        public String NomeFile { get { return _nomeFile; } }

        
        public OdsTablesDictionaryProperty(String nomeFile)
        {
            if (!System.IO.File.Exists(nomeFile)) throw new System.IO.FileNotFoundException();
            this._nomeFile = nomeFile;
            this._lastWrite = System.IO.File.GetLastWriteTime(nomeFile);

            this.load();
            
            System.IO.FileInfo fi = new System.IO.FileInfo(_nomeFile);
            _fsw = new System.IO.FileSystemWatcher(fi.DirectoryName, fi.Name);
            _fsw.Changed +=new System.IO.FileSystemEventHandler(_fsw_Changed);
            _fsw.EnableRaisingEvents = true;
        }        

        void _fsw_Changed(object sender, System.IO.FileSystemEventArgs e)
        {
            if (System.IO.File.GetLastWriteTime(e.FullPath) >= _lastWrite)
                load();
        }

        public override void load()
        {
            SpreadsheetDocument spreadsheetDocument = openSpreadsheet(_nomeFile);

            if (spreadsheetDocument == null) return;
            this.Clear();
            foreach (Table table in spreadsheetDocument.TableCollection)
            {
                String key = table.TableName;
                if (key!=null || !this.ContainsKey(key))
                    this.Add(key, new odsRowsDictionaryProperty(table));
            }
        }

        /// <summary>Apre il foglio di calcolo</summary>
        /// <param name="nomeSpreadsheetFile"></param>
        /// <returns></returns>
        private static SpreadsheetDocument openSpreadsheet(string nomeSpreadsheetFile)
        {
            if (!System.IO.File.Exists(nomeSpreadsheetFile)) throw new System.IO.FileNotFoundException();
            SpreadsheetDocument spreadsheetDocument;
            try
            {
                //Create new spreadsheet document
                spreadsheetDocument = new SpreadsheetDocument();
                
                //Carico il foglio di Lavoro
                spreadsheetDocument.Load(nomeSpreadsheetFile);
            }
            catch (System.IO.IOException ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message, "Errore Apertura File", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return null;
            }
            catch (Exception ex)
            {
                //Errore Generico Apertura Foglio di calcolo
                throw new Exception("AllarmManager.ImportAllarmSpreadsheet: Non sono riuscito ad aprire il foglio di calcolo: " + nomeSpreadsheetFile, ex);
            }
            return spreadsheetDocument;
        }        
    }

    [Obsolete]
    internal class odsRowsDictionaryProperty2 : AbstractDictionaryProperty
    {
        private Table _table;
        public odsRowsDictionaryProperty2(Table table)
        {
            this._table = table;
            load();
        }

        public override void load()
	    {
            for (int i = 1; i < _table.RowCollection.Count; i++)
            {
                String rowKey = _table.RowCollection[i].CellCollection[0].Node.InnerText;
                if (rowKey!="" && !this.ContainsKey(rowKey))
                    this.Add(rowKey, (IDictionaryProperty)new odsRowItems(_table.RowCollection[0], _table.RowCollection[i])) ;
            }
        }
    }

    internal class odsRowsDictionaryProperty : AbstractDictionaryProperty
    {
        private Table _table;
        public odsRowsDictionaryProperty(Table table)
        {
            this._table = table;
            this._propertyKey = _table.TableName;
            load();
        }

        public override void load()
        {
             // intestazione della tabella
             string[] header = new String[_table.RowCollection[0].CellCollection.Count];
             // Prendo l'intestazione della tabella
             for (int i = 0; i < _table.RowCollection[0].CellCollection.Count; i++)
                 header[i] = _table.RowCollection[0].CellCollection[i].Node.InnerText.ToUpper();

             for (int j = 1; j < _table.RowCollection.Count; j++)
             {
                 String[] values = new String[_table.RowCollection[j].CellCollection.Count];
                 // Riempo tutti i dati
                 for (int i = 0; i < _table.RowCollection[j].CellCollection.Count; i++)
                     values[i] = _table.RowCollection[j].CellCollection[i].Node.InnerText;

                 this.Add(values[0], new StringArrayDictionaryProperty(header, values));                 
             }
        }
    }

    [Obsolete]
    internal class odsRowItems : AbstractDictionaryProperty
    {
        private Row _keys;
        private Row _values;
        public odsRowItems (Row keys, Row values)
	    {
            this._keys = keys;
            this._values = values;
            load();
	    }

        public override void load()
        {
            this.Clear();
            
            for (int i=0; i< _keys.CellCollection.Count; i++)            
            {
                String key = _keys.CellCollection[i].Node.InnerText.ToUpper();

                if (key != "" && !this.ContainsKey(key) && i < _values.CellCollection.Count)
                {
                    String value = _values.CellCollection[i].Node.InnerText;
                    this.Add(key, (IDictionaryProperty)new SimpleDictionaryProperty(key, value));
                }
            }
        }
    }

    internal class StringArrayDictionaryProperty : AbstractDictionaryProperty
    {
        private String[] _keys;
        private String[] _values;
        public StringArrayDictionaryProperty(String[] keys, String[] values)
        {
            this._keys = keys;
            this._values = values;

            load();
        }

        public override void load()
        {
            this.Clear();

            for (int i = 0; i < _keys.Length; i++)
            {
                String key = _keys[i];
                if (key != "" && !this.ContainsKey(key) && i < _values.Length)
                    this.Add(key, (IDictionaryProperty)new SimpleDictionaryProperty(key, _values[i]));
            }
        }
    }
}